package com.gdkj.common.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.gdkj.common.LogicResult;
import com.gdkj.constant.CodeConstants;
import com.gdkj.constant.CodeMessage;
import com.xjgks.common.constant.HttpResultConstants;
import org.springframework.stereotype.Component;

import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class Tool {

    public LogicResult verifyToken(String token) throws NoSuchAlgorithmException, InvalidKeySpecException {
        Algorithm algorithm = getAlgorithm();
        JWTVerifier verifier = com.auth0.jwt.JWT.require(algorithm).build();
        DecodedJWT authResult;
        try {
            authResult = verifier.verify(token);
        } catch (Exception e) {
            e.printStackTrace();
            return LogicResult.paramsError(null, CodeMessage.ERROR_CODE.get(CodeConstants.TOKEN_AUTH_FAIL_CODE));
        }
        Long userId = authResult.getClaim("uid").asLong();
        String userLogin = authResult.getClaim("user_login").asString();
        TokenData tokenData = new TokenData(userId, userLogin);
        return LogicResult.success(tokenData, CodeMessage.ERROR_CODE.get(HttpResultConstants.SUCCESS_CODE));
    }

    /**
     * 生成token，自定义过期时间 毫秒
     *
     * @param **username**
     * @param **password**
     * @return String
     */
    public String createToken(Long uid, String userLogin, long expireDate) {
        try {
            // 设置过期时间
            Date date = new Date(System.currentTimeMillis() + expireDate);
            Algorithm algorithm = getAlgorithm();

            // 设置头部信息
            Map<String, Object> header = new HashMap<>(2);
            header.put("typ", "jwt");
            header.put("alg", "RS256");
            // 返回token字符串
            return JWT.create()
                    .withHeader(header)
                    .withClaim("uid", uid)
                    .withClaim("user_login", userLogin)
                    .withExpiresAt(date)
                    .sign(algorithm);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取算法对象
     *
     * @return Algorithm
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public Algorithm getAlgorithm() throws NoSuchAlgorithmException, InvalidKeySpecException {
        // 私钥和加密算法
        byte[] decoded = Base64.getDecoder().decode("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCafeieanl4Bq3qbOsWmrC/bWwgQ7FWi2Em69jSCis8Xgkmd9ZjAak2dqONSfMqvYF19fNgLKRv1WwV9T0PrA7DOQT2N0qugn6lXRd9SvC5c4bjvBrg3q8G2GM3vYNW0B4Y5Gfgcyp3sDJp2Zy1HPbeKeVxc8Q/DIA3PKC3jMBeqQIDAQAB");
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
        byte[] decodedPrivate = Base64.getDecoder().decode("MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJp96J5qeXgGreps6xaasL9tbCBDsVaLYSbr2NIKKzxeCSZ31mMBqTZ2o41J8yq9gXX182AspG/VbBX1PQ+sDsM5BPY3Sq6CfqVdF31K8LlzhuO8GuDerwbYYze9g1bQHhjkZ+BzKnewMmnZnLUc9t4p5XFzxD8MgDc8oLeMwF6pAgMBAAECgYAFrcUkNZO7drtj15cYoJ0InFQSJ4rYPI1YqeixZ9BJCsfZUyRdRU1cBCZk5if7FTYyCNVmXp24wqaTdA1HizKLqee56ouEjSomwkjrAmJejwVnsWBMmMCBuXgz4rQJkx5KyM0eunQ9zZZnbmjlGOvNye1am2tOYqtc0qtsy4Vh9QJBAMxG47rQqjQnkhEdKDe6whO7lyPUKOVxO+XlwAOeRhBcY6OAxP0zR6DMWqiOhg0wyjKgXaHLb7NtpJn2EFGbkm8CQQDBm/qnQa84Di78hgsvwbcKW79+dDRNSdtQpsSsnpSBSP9rNSh4hOwRE7MTsNOVk2s9mqw7nJcHRdkWePoFCMxnAkEAkIZLEl4VPWcNqbwGOz+PleRvrzKoaIRvi1y8OBMfoO2stP4i4L0KHVLXhU+oueZd9+mLtS+4bKrS/PahXwuBUwJAAw+AKtyy9GPlAkDsNFkPl65TnKAho4cjXGcGfOQU3OZWg09X0G/pe2ugTRNihN7LtzGWv2p+SLMl92D6MtIsyQJALDQpf1tFM2dyJKJOjJvTH2K5OG81yL61IZcsac/nPsF92YSqEkkoNoNNC+GWKKFsWo+Riw9ZQlHRTBFtqK06bw==");
        PKCS8EncodedKeySpec a = new PKCS8EncodedKeySpec(decodedPrivate);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(a);
        return Algorithm.RSA256(pubKey, priKey);
    }
}
